//****************************************************************************************
//*
//* File Name: uart_buffer.c 
//* Level: bsp_UART
//* Version: v4.0
//* Date: 2024-07-09 13:05:10
//* Author: su
//* 
//****************************************************************************************/

//******************************** Includes *********************************//
#include <string.h>
#include <stdint.h>
#include "stdlib.h"

#include "cmsis_os.h"
#include "queue.h"
#include "portmacro.h"
#include "semphr.h"
#include "adtask.h"

#include "hal_uart.h"
#include "hal_adc.h"
#include "elog.h"

//******************************** code *********************************//
#define WAITMAX 0xffffffff
SemaphoreHandle_t Send_to_taskxQueue;
SemaphoreHandle_t mutex;
QueueHandle_t dcxQueue;
BaseType_t TaskWoken = pdFALSE;
uint8_t flag = 0;
uint8_t addressflag;

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	HAL_ADC_Stop_DMA(&hadc1);
	//不停DMA的话，可能在DMA回调时产生新的DMA事件，发生DMA错误
	xSemaphoreGiveFromISR(Send_to_taskxQueue, &TaskWoken);
	//二值信号量-做中断和生产者线程的回调
	// 可以通过判断TaskWoken的值来检查是否触发绝对的调用链衔接
}

//线程A，生产者线程
void adc_thread(void *para)
{
	//变量的生命周期只和它所定义的地址有关
	//buffer2它是局部变量，它的生命周期和线程是绑定的，存在栈里
	//malloc是在堆区创建一块内存，这块内存只要没回收，就是永生的。
	uint32_t *buffer2 = malloc(sizeof(uint32_t));//先申请
	uint32_t *buffer1 = malloc(sizeof(uint32_t));
	if ( (NULL == buffer2)  &&                   //判空
			 (NULL == buffer1)    )
	{
		uartprintf("invalid memory \r\n");
		while(1);
	}
	memset(buffer2,0,sizeof(uint32_t));				// 初始化内存
	memset(buffer1,0,sizeof(uint32_t));
	
	Send_to_taskxQueue = xSemaphoreCreateBinary();
	mutex = xSemaphoreCreateMutex();
	dcxQueue = xQueueGenericCreate( 1, sizeof(uint32_t),queueQUEUE_TYPE_BASE);
	uint32_t temp = 0;
	HAL_ADC_Start_DMA(&hadc1,buffer1,sizeof(uint32_t)); //开启DMA
	while(1)
	{
		xSemaphoreTake(Send_to_taskxQueue,WAITMAX);
		if(1 == flag)
		{

			xQueuePeek(dcxQueue,&temp,0);
			if(temp == 0) //判断是否数据没被拿走
			{
				//数据被线程adc_information_dispose拿走了
				
				xSemaphoreTake(mutex,0xffffffff); //虽然拿走了但是还需要检查是否处理完数据了	
				xSemaphoreGive(mutex); //确定线程adc_information_dispose处理完数据处于空闲状态了
					
				if(0 == addressflag)
				{
					xQueueSendToBack(dcxQueue,buffer1,WAITMAX);
					HAL_ADC_Start_DMA(&hadc1,buffer2,sizeof(uint32_t));
					addressflag = 1;
				}
				else
				{
					xQueueSendToBack(dcxQueue,buffer2,WAITMAX);
					HAL_ADC_Start_DMA(&hadc1,buffer1,sizeof(uint32_t));
					addressflag = 0;
				}	
				
			}
			else
			{				
				uartprintf("adc_information_dispose data no\r\n");	
			}
			
		}
		else
		{
			flag = 1;
			xQueueSendToBack(dcxQueue,buffer1,WAITMAX);
			HAL_ADC_Start_DMA(&hadc1,buffer2,sizeof(uint32_t));
			addressflag = 1;
		}

	}
}


void adc_information_dispose(void *para)
{
	uint32_t adc_data;
	while(1)
	{
		xQueueReceive( dcxQueue,&adc_data,WAITMAX); 
		xSemaphoreTake(mutex,0);
		uartprintf("adc_data:%d \r\n",adc_data);
		uartprintf("adc_dc====:%.2f V\r\n",adc_data*(3.3/4095.0));
		xSemaphoreGive(mutex);
	}
	
	
}

void DMA2_Stream0_IRQHandler(void)
{
	
	
	HAL_DMA_IRQHandler(&DMA_Init_Handle);
}







